﻿#ifndef HTTPSERVER_H
#define HTTPSERVER_H
#include "module_global.h"
#include "httpheader.h"
#include "HttpCmdDef.h"
#include "httpdefine.h"
#include <iostream>
#include <QMutex>
#include <mutex>
#include <vector>
#include <atomic>
/*****************************************************************************
**FileName: MyHeader.h
**Function: http服务器启动/停止，接收客户端http请求及处理
**Version record:
**Version       Author        Data            Description
**v1.0.0        chexlong      2022.09         初稿
**v1.0.2        chexlong	  2022.09         1，支持多线程
**											  2，添加HTTP请求命令模式
*****************************************************************************/

class CHttpServer;
typedef std::shared_ptr<CHttpServer>		CHttpServerPtr;
typedef vector<CHttpServerPtr>			HTTPServerVec;


class MODULE_EXPORT CHttpServerMgr
{
public:
    static CHttpServerMgr* GetInstance(int listenPort);

    CHttpServerMgr(const CHttpServerMgr&) = delete;

    CHttpServerMgr& operator=(const CHttpServerMgr&) = delete;
public:
     // 启动HTTP服务，返回是否启动成功
    int Start();

    // 停止HTTP服务，返回是否停止成功
    int Stop();

    // [FDD-2025-03-021][API-006] 正确关闭HTTP服务，等待线程join
    int Shutdown();

private:
     CHttpServerMgr(int listenPort);
     ~CHttpServerMgr();
    //监听线程
    void ListenThreadFunc();

    //创建套接字，绑定地址和端口，开启监听
    int BindSocket(int port, int backlog);
private:
    static CHttpServerMgr*      instance;
    std::atomic<bool>           m_isRunning;        // HTTP服务是否正在运行
    std::atomic<bool>           m_shouldStop;       // [FDD-2025-03-021] 停止标志
    int                         m_listenPort;       // 监听端口号
    int                         m_listenSocket;     // 监听套接字
    HTTPServerVec               m_httpServerPool;   // HTTP消息处理线程池
    std::vector<std::thread>    m_workerThreads;    // [FDD-2025-03-021] 工作线程列表
    std::thread                 m_listenThread;     // [FDD-2025-03-021] 监听线程
    static QMutex               m_mutex;            // 互斥锁，保证多线程安全
};

class CHttpServer
{
public:

    CHttpServer(const int& listenSocket);
    ~CHttpServer();

    //启动http服务
    int Start();
    //停止http服务
    int Stop();

private:
    //上传post接口/xpoc/ue-fse-uploadfd请求报文如下：
    //请求头header如下
    //在这里插入图片描述
    int HttpSipMsgUpFileAck(struct evhttp_request* req, char* keyFileName, char* aucFileName, char* aucSessionId);
    //文件上传接口的回调处理函数
    void OnRequestUpFile(struct evhttp_request* req, void* arg);
    //处理文件请求
    void OnRequestFile(struct evhttp_request* pstReq);

    //处理数据请求
    void OnRequestData(struct evhttp_request* pstReq);

    //处理系统各种业务的GET请求
    void RequestProcessGet(struct evhttp_request* pstReq);

    //处理系统各种业务的POST请求
    void RequestProcessPost(struct evhttp_request* pstReq);

    //http请求回调函数
    static void HttpReqCallback(struct evhttp_request* pstReq, void* userData);

    //http工作线程函数
    void WorkThread();

    //获取http请求负载数据
    std::string GetContentFromRequest(struct evhttp_request* req);

    //发送http请求应答消息
    int SendReply(struct evhttp_request* pstReq, int code, const char* reason, const std::string& response);
public:
    // [FDD-2025-03-021] 使用 thread_local 替代 static，避免竞态
    static int rspHttp(const char* const rspStr);
    static std::string getThreadLocalResponse();
private:
    static int Login(const struct evhttp_request* pstReq, const string& data, void* param);
    static int Logout(const struct evhttp_request* pstReq, const string& data, void* param);
    static int Heartbeat(const struct evhttp_request* pstReq, const string& data, void* param);
private:

    //event base
    event_base* m_base;

    //http server
    evhttp* m_http;

    //http服务工作线程
    std::thread				m_thread;

    //http监听套接字
    int						m_listenSocket;

    // [FDD-2025-03-021] 移除静态 rsp，改用局部变量
    // static std::string rsp;

    // [FDD-2025-03-021] 添加互斥锁保护 m_httpReqMap
    mutable std::mutex      m_mapMutex;

private:
    //HTTP请求消息映射列表
    struct HTTPReqInfo httpReqInfo[60] =
    {
        {"/terminal/Login",         CHttpServer::Login,},
        {"/terminal/Logout",		CHttpServer::Logout,},
        {"/terminal/Heartbeat", 	CHttpServer::Heartbeat,},
        { NULL }
    };

    HTTP_REQ_INFO_MAP	m_httpReqMap;
};


#endif // HTTPSERVER_H
